#pragma once
#include <QObject>
#include <QTcpSocket>
#include <QHostAddress>
#include <QByteArray>
#include <QString>
#include <QTimer>
#include <QMutex>
#include <QWaitCondition>

class TcpClient : public QObject
{
    Q_OBJECT

public:
    enum ConnectionStatus {
        Disconnected,
        Connecting,
        Connected
    };

    explicit TcpClient(QObject* parent = nullptr);
    ~TcpClient();

    // 连接服务器
    bool connectToServer(const QString& host, quint16 port, int timeoutMs = 3000);
    void disconnectFromServer();

    // 同步发送和接收
    bool sendData(const QByteArray& data, int timeoutMs = 3000);
    bool sendText(const QString& text, int timeoutMs = 3000);
    QByteArray receiveData(int timeoutMs = 3000);
    QString receiveText(int timeoutMs = 3000);
    QByteArray sendAndReceive(const QByteArray& data, int timeoutMs = 3000);
    QString sendTextAndReceive(const QString& text, int timeoutMs = 3000);

    // 异步发送
    void sendDataAsync(const QByteArray& data);
    void sendTextAsync(const QString& text);

    // 状态查询
    bool isConnected() const;
    ConnectionStatus connectionStatus() const;
    QString errorString() const;

signals:
    // 异步接收信号
    void dataReceived(const QByteArray& data);
    void textReceived(const QString& text);
    void connectionStatusChanged(TcpClient::ConnectionStatus status);
    void errorOccurred(const QString& errorString);

private slots:
    void onConnected();
    void onDisconnected();
    void onReadyRead();
    void onErrorOccurred(QAbstractSocket::SocketError error);

private:
    QTcpSocket* m_socket;
    ConnectionStatus m_status;
    QByteArray m_receivedData;
    QMutex m_mutex;
    QWaitCondition m_waitCondition;
    bool m_dataReceived;

    void setConnectionStatus(ConnectionStatus status);
    void clearReceiveBuffer();
};
